﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace CoursePack
{

    [Serializable]
    public enum CourseStatus { NotStarted, InProgress, Completed };

    [Serializable]
    public class Course : CourseDescription
    {
 
        private Class m_Lecture;
        private Class m_Tutorial;
        private Class m_Lab;

        private ESession m_Session;

        /// <summary>
        /// Course of a specific semester
        /// </summary>
        /// <param name="_CourseName"></param>
        /// <param name="_CourseNumber"></param>
        /// <param name="_CourseTitle"></param>
        /// <param name="_Lect"></param>
        /// <param name="_Tut"></param>
        /// <param name="_Lab"></param>
        public Course(string _CourseName, string _CourseNumber, string _CourseTitle, Class _Lect, Class _Tut, Class _Lab, string _Credits, string _Session, string _Prereq, string _SpecialNotes,CourseStatus _Status) 
            : base(_CourseName, _CourseNumber, _CourseTitle, _Credits, _Prereq,_SpecialNotes,_Status)
        {
            this.m_Lecture = _Lect;
            this.m_Tutorial = _Tut;
            this.m_Lab = _Lab;

            this.m_Session = (ESession)Enum.Parse(typeof(ESession),_Session);
            this.m_CourseStatus = _Status;
        }


        public override bool Equals(object obj)
        {

            if (this.Lecture.Section != ((Course)obj).Lecture.Section)
                return false;

            if ((this.HasTutorial && ((Course)obj).HasTutorial) && (this.Tutorial.Section != ((Course)obj).Tutorial.Section))
                return false;
            else if (this.HasTutorial ^ ((Course)obj).HasTutorial)
                return false;


            if ((this.HasLab && ((Course)obj).HasLab) && (this.Lab.Section != ((Course)obj).Lab.Section))
                return false;
            else if (this.HasLab ^ ((Course)obj).HasLab)
                return false;

            return true;
           
        }

        public int CourseConficts(Course _C2)
        {
            int conflictscount = 0;
            

            conflictscount += this.m_Lecture.ClassConflicts(_C2.m_Lecture);

            if (_C2.HasTutorial)
                conflictscount += this.m_Lecture.ClassConflicts(_C2.Tutorial);

            if (_C2.HasLab)
                conflictscount += this.m_Lecture.ClassConflicts(_C2.Lab);



            if (this.HasTutorial)
            {
                conflictscount += this.m_Tutorial.ClassConflicts(_C2.Lecture);

                if (_C2.HasTutorial)
                    conflictscount += this.m_Tutorial.ClassConflicts(_C2.Tutorial);

                if (_C2.HasLab)
                    conflictscount += this.m_Tutorial.ClassConflicts(_C2.Lab);
            }


            if (this.HasLab)
            {
                conflictscount += this.m_Lab.ClassConflicts(_C2.Lecture);
                if (_C2.HasTutorial)
                    conflictscount += this.m_Lab.ClassConflicts(_C2.Tutorial);
                if (_C2.HasLab)
                    conflictscount += this.m_Lab.ClassConflicts(_C2.Lab);

            }
            

            return conflictscount;
        }

        #region Accessors
 
        public int StartTime
        {
            get
            {
                if (this.HasLab)
                {
                    return this.m_Lab.StartTime;
                }
                else if (this.HasTutorial)
                {
                    return this.m_Tutorial.StartTime;
                }
                else
                {
                    return this.m_Lecture.StartTime;
                }
            }
        }

        public int EndTime
        {
            get
            {
                if (this.HasLab)
                {
                    return this.m_Lab.EndTime;
                }
                else if (this.HasTutorial)
                {
                    return this.m_Tutorial.EndTime;
                }
                else
                {
                    return this.m_Lecture.EndTime;
                }
            }
        }

        public string Campus
        {
            get { return this.m_Lecture.Campus; }
        }

        public Class Lecture
        {
            get { return this.m_Lecture; }
        }

        public Class Tutorial
        {
            get { return this.m_Tutorial; }
        }

        public Class Lab
        {
            get { return this.m_Lab; }
        }

        public string DaysLecture
        {
            get { return this.m_Lecture.Days; }
        }

        public string DaysTutorial
        {
            get { return this.m_Tutorial.Days; }
        }

        public string DaysLab
        {
            get { return this.m_Lab.Days; }
        }

        public bool HasLab
        {
            get { return (this.m_Lab != null) ? true : false; }
        }

        public bool HasTutorial
        {
            get { return (this.m_Tutorial != null) ? true : false; }
        }

        public string Prerequisite
        {
            get { return (this.m_strPrerequisites) == "" ? "None." : this.m_strPrerequisites; }
        }

        public List<Prerequisite> Prerequistes
        {
            get { return this.m_Prerequisites; }
        }

        public string SpecialNotes
        {
            get { return this.m_SpecialNotes; }
        }

        public ESession Session
        {
            get { return this.m_Session; }
        }

        #endregion

    }
}
